/**
 * 
 */
package edu.cmu.mism.dgjava.algorithm;

import edu.cmu.mism.dgjava.algorithm.impl.BinomialAmericanAlg;
import edu.cmu.mism.dgjava.algorithm.impl.BinomialEuropeanAlg;
import edu.cmu.mism.dgjava.algorithm.impl.BlackScholesAlg;
import edu.cmu.mism.dgjava.algorithm.impl.ImplicitFiniteDifferenceAlg;
import edu.cmu.mism.dgjava.algorithm.impl.MonteCarloSimulationAlg;
import edu.cmu.mism.dgjava.data.models.option.BinomialAmerican;
import edu.cmu.mism.dgjava.data.models.option.BinomialEuropean;
import edu.cmu.mism.dgjava.data.models.option.BlackScholes;
import edu.cmu.mism.dgjava.data.models.option.ImplicitFiniteDifference;
import edu.cmu.mism.dgjava.data.models.option.MonteCarloSimulation;

/**
 * OptionAlgorithmManager that handles the mapping of input pricing models to
 * the concrete algorithm implmentations
 * 
 * @author Christian
 * 
 */
public class OptionAlgorithmManager {
	// singleton instance of the manager
	private static OptionAlgorithmManager instance;

	public static OptionAlgorithmManager getInstance() {

		if (instance == null) {
			instance = new OptionAlgorithmManager();
		}
		return instance;
	}

	/**
	 * Gets the algorithm instance for the given underlying type model and the
	 * pricing model
	 * 
	 * @version 1.0
	 * @param underlyingModel
	 *            - the underlying type model, could be either <tt>Equity</tt>,
	 *            <tt>Futures</tt>, <tt>Index</tt> and <tt>Currency</tt>
	 * @param pricingModel
	 *            - the pricing model for the option calculation, could be
	 *            either <tt>BinomialAmerican</tt> and <tt>BinomialEuropean</tt>
	 * @return the concrete algorithm handler instance
	 */
	public IOptionAlgorithm getAlgorithm(Object underlyingModel,
			Object pricingModel) {
		if (pricingModel instanceof BinomialAmerican) {
			return new BinomialAmericanAlg(underlyingModel, pricingModel);
		}

		else if (pricingModel instanceof BinomialEuropean) {
			return new BinomialEuropeanAlg(underlyingModel, pricingModel);
		}
		
		else if (pricingModel instanceof MonteCarloSimulation){
			return new MonteCarloSimulationAlg(underlyingModel, pricingModel);
		}
		
		else if (pricingModel instanceof ImplicitFiniteDifference){
			return new ImplicitFiniteDifferenceAlg(underlyingModel, pricingModel);
		}
		
		else if (pricingModel instanceof BlackScholes){
			return new BlackScholesAlg(underlyingModel, pricingModel);
		}
		// TODO For phase 1, we only support equity type option, but we might
		// want to extend this method in the future to handle different types
		// of option calculations
		return null;
	}
}
